// 深度优先深拷贝
function myDeepCopy(target, cache = new WeakMap()) {
  let result;
  let targetType = typeof target;

  if (["string", "nmumber", "undefined"].includes(targetType)) {
    return target;
  }

  // weakmap存储，避免循环引用
  if (cache.get(target)) {
    return cache.get(target);
  }
  // 根据各种类型分别复制
  if (typeof target === "function") {
    return function (...args) {
      target.call(this, ...args);
    };
  }
  if (target instanceof Date) {
    return new Date(target);
  }
  // Regexp, Map, Set等略过

  if (target instanceof Array) {
    result = [];
  } else {
    result = {};
  }

  if (!cache.get(target)) {
    cache.set(target, result);
  }

  const keys = Object.keys(target);
  for (let i = 0; i < keys.length; i++) {
    const item = target[keys[i]];

    result[keys[i]] = myDeepCopy(item, cache);
  }

  return result;
}

const copyItem = (target) => {
  let targetType = typeof target;
  if (["string", "number", "undefined"].includes(targetType)) {
    return target;
  } else if (targetType === "function") {
    return function () {
      target.apply(this, arguments);
    };
  } else if (target instanceof Array) {
    return [];
  } else {
    return {};
  }
};

function myDeepCopyBfs(target, cache = new Map()) {
  // 避免循环引用

  let result = copyItem(target);

  const queue = [];
  if (result !== target) {
    queue.push([target, result]);
    cache.set(target, result);
  }

  cache.set(target, result);
  while (queue.length) {
    const [t, r] = queue.shift();

    const keys = Object.keys(t);

    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];

      if (cache.has(target[key])) {
        r[key] = cache.get(t[key]);
      } else {
        r[key] = copyItem(t[key]);
        if (r[key] !== t[key]) {
          cache.set(t[key], r[key]);
          queue.push([t[key], r[key]]);
        }
      }
    }
    console.log(result);
  }
  return result;
}
const c = { aa: 3 };
const obj = { a: 2, b: 2, c };
const obj2 = myDeepCopyBfs(obj);

obj.d = c;
const obj3 = myDeepCopyBfs(obj);
